/*
 *  $Id: Group.cs 975 2009-12-16 17:13:22Z thenn.erannor $
 *	This file is a part of Ragima CCG.
 *	(C) 2008 Ragima development group.
 *
 *	Licensed under the terms of the GNU GPL License version 2.
 *
 */

using System.Collections;
using System.Collections.Generic;

namespace Ragima {
    /// <summary>
    /// Абстрактная группа эффектов
    /// </summary>
    public abstract class GroupAffect: Affect, IEnumerable<Affect> {
        private List<Affect> _affects;

        public GroupAffect(): base() {
            _affects = new List<Affect>();
        }

        public override int BaseWeight {
            get {
                int weight = 0;
                foreach (Affect affect in _affects)
                    weight += affect.BaseWeight;
                return weight;
            }
        }
        public override int GetWeight(Card card) {
            int weight = 0;
            foreach (Affect affect in _affects)
                weight += affect.GetWeight(card);
            return weight;
        }

        /// <summary>
        /// Список иконок всех вложенных эффектов
        /// </summary>
        public override IEnumerable<AffectIcon> GetIcons() {
            if (HasIcon) yield return Icon;
            foreach (Affect affect in _affects)
                foreach (AffectIcon icon in affect.GetIcons())
                    yield return icon;
        }

        public override IEnumerable<Affect> GetIconAffects() {
            if (HasIcon) yield return this;
            foreach (Affect affect in _affects)
                foreach (Affect sub in affect.GetIconAffects())
                    yield return sub;
        }

        /// <value>
        /// Группа эффектов может быть развеяна, только если могут быть развеяны все подэффекты
        /// </value>
        public override bool Dispellable {
            get { return _affects.TrueForAll(delegate(Affect affect) { return affect.Dispellable; }); }
        }

        /// <value>
        /// Группа эффектов завершена, если завершены все подэффекты
        /// </value>
        public override bool IsEnded {
            get { return _affects.Count > 0 && _affects.TrueForAll(delegate(Affect affect) { return affect.IsEnded; }); }
        }

        /// <value>
        /// Установка владельца всем подэффектам
        /// </value>
        public override AbstractObject Owner {
            set {
                base.Owner = value;
                foreach (Affect affect in _affects) affect.Owner = value;
            }
        }

        public override void SetAffect() {
            base.SetAffect();
            SetAffects();
        }
        protected void SetAffects() {
            foreach (Affect affect in _affects) affect.SetAffect();
        }

        public override void ResetAffect() {
            base.ResetAffect();
            ResetAffects();
        }
        protected void ResetAffects() {
            foreach (Affect affect in _affects) affect.ResetAffect();
        }

        /// <summary>
        /// Добавление подэффекта
        /// </summary>
        /// <param name="affect">Добавляемый эффект</param>
        public void Add(Affect affect) {
            _affects.Add(affect);
            affect.Owner = Owner;
        }

        /// <summary>
        /// Добавление копий подэффектов из другой группы
        /// </summary>
        /// <param name="group">Откуда добавлять подэффекты</param>
        public void AddCloned(GroupAffect group) {
            foreach (Affect affect in group)
                Add(affect.Clone());
        }

        /// <summary>
        /// Удаление подэффекта
        /// </summary>
        /// <param name="affect">Удаляемый эффект</param>
        /// <returns>true, если эффект удален</returns>
        public bool Remove(Affect affect) {
            bool b = _affects.Remove(affect);
            if (b) affect.Owner = null;
            return b;
        }

        /// <summary>
        /// Удаление всех подэффектов
        /// </summary>
        public void Clear() {
            foreach (Affect affect in _affects) affect.Owner = null;
            _affects.Clear();
        }

        #region Реализация IEnumerable<Affect>
        IEnumerator IEnumerable.GetEnumerator() {
            return _affects.GetEnumerator();
        }
        IEnumerator<Affect> IEnumerable<Affect>.GetEnumerator() {
            return _affects.GetEnumerator();
        }
        #endregion
    }
}